﻿using MCUPackage;
using MCUPackage.DesignEditor;
using MCUPackage.Utils;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SxPackages.STC8.Models
{
	/// <summary>
	/// 系统配置
	/// </summary>
	[Serializable]
	class SysOptions
	{
		/// <summary>
		/// 所属选项
		/// </summary>
		protected STC8HUSOP20 mParent = null;

		private string mFreq = "24.000";
		/// <summary>
		/// 系统主频
		/// </summary>
		[Category("系统配置"),
		DisplayName("系统主频"),
		DefaultValue("24.000"),
		Description("系统运行主频(MHz)"),
		Editor(typeof(FreqEditor), typeof(UITypeEditor))]
		public string Freq
		{
			get => this.mFreq;
			set
			{
				if (value != mFreq)
				{
					double freq = Convert.ToDouble(value);
					this.FreqValue = freq * 1000;
					mFreq = TemplateHelper.GetFreqStr(freq);
					mParent.UpdateMsg(mFreq, MCUMsgTypes.Freq);
				}
			}
		}
		/// <summary>
		/// 主频具体的值(KHz)
		/// </summary>
		[Browsable(false)]
		[JsonIgnore]
		public double FreqValue { get; private set; } = 24000;

		[Category("系统配置"),
		DisplayName("printf函数接口"),
		DefaultValue(PrintfPort.不设置),
		Description("printf函数输出默认使用哪个接口")]
		public PrintfPort Port { get; set; }

		/// <summary>
		/// 使能内置Flash
		/// </summary>
		[Category("系统配置"),
		DisplayName("使用EEPROM"),
		DefaultValue(false),
		Description("是否使用芯片内置EEPROM存储器")]
		public bool EnableFlash { get; set; }

		[Category("系统配置"),
		DisplayName("使能系统嘀嗒"),
		DefaultValue(true),
		Description("使用定时器0作为系统嘀嗒, 周期为1ms, 强制开启")]
		public bool EnableTick { get; } = true;

		/// <summary>
		/// 使能看门狗
		/// </summary>
		[Category("看门狗"),
		DisplayName("启用看门狗"),
		DefaultValue(false),
		JsonProperty(Order = 100),
		Description("是否启用系统看门狗")]
		public bool EnableWDG { get; set; } = false;
		/// <summary>
		/// IDLE模式下继续计数
		/// </summary>
		[Category("看门狗"),
		DisplayName("IDLE模式控制"),
		DefaultValue(false),
		Description("在IDLE模式下是否启用系统看门狗")]
		public bool EnableWDGIdle { get; set; } = false;

		private int mWDGPS = 64;
		/// <summary>
		/// 分频系数
		/// </summary>
		[Category("看门狗"),
		DisplayName("看门狗分频系数"),
		DefaultValue(64),
		TypeConverter(typeof(IntCollectionConvertor)),
		IntCollection(new int[] { 2, 4, 8, 16, 32, 64, 128, 256 }),
		Description("分频系数越大看门狗溢出时间越长")]
		public int WDGPS
		{
			get => mWDGPS;
			set
			{
				if (mWDGPS != value)
				{
					mWDGPS = value;
					// 计算溢出时间
					double ms = GetOverflowTime();
					if (ms > 1000)
					{
						mParent.UpdateMsg(string.Format("看门狗溢出时间{0:F2}秒", ms / 1000));
					}
					else
					{
						mParent.UpdateMsg(string.Format("看门狗溢出时间{0:F2}毫秒", ms));
					}
				}
			}
		}

		/// <summary>
		/// 获取溢出时间, 单位ms
		/// </summary>
		/// <returns></returns>
		private double GetOverflowTime()
		{
			double result = 12 * 32768 * mWDGPS;
			// 除以MHz得出的是us数, 除以KHz得出的为ms数
			return result / (this.FreqValue);
		}

		public SysOptions(STC8HUSOP20 aParent)
		{
			this.mParent = aParent;
		}

		public override string ToString()
		{
			return string.Empty;
		}

		/// <summary>
		/// 初始化模板
		/// </summary>
		private const string TEMPLATE =
@"	attr.WDT_Enable     = ENABLE;			//看门狗使能   ENABLE或DISABLE
	attr.WDT_IDLE_Mode  = {0};	//IDLE模式是否停止计数		WDT_IDLE_STOP,WDT_IDLE_RUN
	// {1}
	attr.WDT_PS         = WDT_SCALE_{2};	//看门狗定时器时钟分频系数	WDT_SCALE_2,WDT_SCALE_4,WDT_SCALE_8,WDT_SCALE_16,WDT_SCALE_32,WDT_SCALE_64,WDT_SCALE_128,WDT_SCALE_256
	WDT_Inilize(&attr);					//初始化";

		public bool AppendConfig(List<string[]> aLst)
		{
			if (!this.EnableWDG)
			{
				return false;
			}

			string name = "WDT_Config";
			StringBuilder tmpSb = new StringBuilder();
			tmpSb.Append(TemplateHelper.GetFunctionCommit("看门狗模块初始化"));
			tmpSb.AppendLine($"PRIVATE void {name}(void)").AppendLine("{");
			tmpSb.AppendLine("\tWDT_InitTypeDef attr;");
			tmpSb.AppendLine();
			double ms = GetOverflowTime();
			string str = string.Empty;
			if (ms > 1000)
			{
				str = string.Format("看门狗溢出时间{0:F2}秒", ms / 1000);
			}
			else
			{
				str = string.Format("看门狗溢出时间{0:F2}毫秒", ms);
			}
			tmpSb.AppendFormat(TEMPLATE, this.EnableWDGIdle ? "WDT_IDLE_RUN" : "WDT_IDLE_STOP", str, this.WDGPS);
			tmpSb.AppendLine();
			tmpSb.AppendLine("}");
			aLst.Add(new string[] { tmpSb.ToString(), $"{name}();" });

			return true;
		}

		/// <summary>
		/// 创建系统文档
		/// </summary>
		/// <param name="aPath"></param>
		/// <returns></returns>
		public bool Cenerate(string aPath)
		{
			// 创建数据类型文件
			string file = "SxTypes.h";
			string path = PathTypes.Inc.ToFilePath(aPath, file);

			PrjTemplate.Append(PathTypes.Inc, file);
			mParent.CreateByTemplate(PathTypes.Inc, aPath, file, true, null, "常用数据类型定义");

			// 创建Config文件
			file = "Config.h";
			StringBuilder otherHeader = new StringBuilder();
			if (this.EnableWDG)
			{
				otherHeader.AppendLine("#include \"STC8G_H_WDT.h\"");
			}
			if (mParent.mUSB.Enable && this.Port == PrintfPort.USB_HID)
			{
				otherHeader.AppendLine("#include \"stc32_stc8_usb.h\"");
			}
			var pairs = TemplateHelper.CreatePairs();
			pairs["Freq"] = Convert.ToString((UInt32)(this.FreqValue * 1000));
			pairs["OtherHeader"] = otherHeader.ToString();
			mParent.CreateByTemplate(PathTypes.Inc, aPath, file, true, pairs, "系统配置文件, 其他源文件引用这一个就可以了");

			// 复制串口头文件
			file = "STC8G_H_UART.h";
			pairs.Clear();
			pairs["PrintfUart"] = (this.Port >= PrintfPort.串口1 && this.Port <= PrintfPort.串口2) ? $"UART{(int)this.Port}" : "0";
			foreach (var uart in mParent.mUarts.All)
			{
				pairs.EnableKey($"UseUart{uart.Id}", uart.Enable);
			}
			mParent.CreateByTemplate(PathTypes.Drivers_STC_Inc, aPath, file, false, pairs);

			// 复制USB头文件
			if (mParent.mUSB.Enable)
			{
				file = "stc32_stc8_usb.h";
				pairs.Clear();
				pairs.EnableKey("UseHID", this.Port == PrintfPort.USB_HID);
				mParent.CreateByTemplate(PathTypes.Drivers_STC_Inc, aPath, file, false, pairs);
			}

			return true;
		}
	}
}
